package moa.sequencestreams.generator;

import moa.sequencestreams.generator.Transaction;
import java.lang.String;

import org.apache.commons.math.random.RandomDataImpl;


public class CustSeq {
	private  int cid;				// customer-id
	private  int slen;			// expected number of transactions in sequence
	private  int tlen;			// avg. expected number of items in a transaction
	private  int ntrans;			// number of transactions in sequence
	private  int nitems;			// number of items in sequence
	private  int maxsize;			// size of array trans
	private  Transaction[] trans;	// transaction in the sequence
	private int patlen;

	public  CustSeq(int cid, int seq_len, int tot_items)
	{
		 this.cid=cid;
		 this.slen=seq_len;
		 this.tlen=tot_items;
		 this.nitems=0;
		 this.ntrans=seq_len;
		 this.maxsize=5 * seq_len;
		 // we reallocate memory if necessary
		  trans = new Transaction [maxsize];
		  for (int i = 0; i < maxsize; i++)
		    trans[i] = null;
	}

	public boolean add(ArrayString pat, StringSet lits) // adds pattern to transaction
	{
		RandomDataImpl rd;
		rd = new RandomDataImpl();
		  int  i;
		  int pos;
		  int newitems, olditems;
		  boolean corrupt;	// if TRUE, corrupt transactions too

		  if (rd.nextUniform(0, 1) > pat.conf_lvl() )
		    corrupt = true;		// corrupt transactions
		  else
		    corrupt = false;	// don't corrupt transactions

		  // corrupt the pattern by reducing its length;
		  // conf_lvl for a pattern is decided at the time of pattern creation
		  patlen = pat.size();
		  if ( corrupt )
		    while ( patlen > 0 && rd.nextUniform(0, 1) > pat.conf_lvl() )
		      patlen--;
		  if ( patlen == 0 )	// no trans. left in sequence
		    return true;

		  // allows transactions to be dropped randomly from the sequence
		  Choose shuffle = new Choose(pat.size(), patlen);

		  // calculate # of items in pattern
		  for (newitems = 0, i = 0; i < patlen; i++)	  
		  {
			  newitems += lits.get_pat( pat.item( shuffle.pos(i) ) ).size(); 
		  }
		    

		  // in half of the cases, we drop the pattern that won't fit
		  if ( (patlen > slen) || (newitems + nitems > slen * tlen) )
		  {
			    if ( rd.nextUniform(0, 1) > 0.5 ) {
				      return false;		
			    }	  
		  }

		  
		// need to allocate more memory
		  if ( patlen > maxsize ) {	
		    Transaction[] old_trans = trans;
		    int oldsize = maxsize;
		    maxsize = patlen*2;
		    trans = new Transaction [maxsize];
		    for (i = 0; i < oldsize; i++)
		    	trans[i] = old_trans[i];
		    	//trans.add(old_trans[i]);
		    for (; i < maxsize; i++)
		      trans[i] = null;
		    //delete [] old_trans;
		  }

		  // add new sequence
		  Choose shuffle1 = null;
			 //System.out.println("ntrans " + ntrans + "patlen" + patlen);
		  if (ntrans > patlen)
		  {
			    shuffle1 = new Choose(ntrans, patlen);
			    //System.out.println("Choose");
		  }
		  
		  for (i = 0; i < patlen; i++)
		  {
			  //System.out.print("patlen" + patlen);
			  //lits.get_pat(pat.item( shuffle.pos(i))).display(10);
			if ( shuffle1 != null )
			{	
					pos = shuffle1.pos(i);
					//System.out.println("shuffle not null " + pos);
			}		
		    else
		    {	
					pos = i;
					//System.out.println("shuffle null " + pos);
		    }		
			// We have to create the transaction object to allow it to receive the patterns
		    if ( trans[pos] == null )
		    {	
		    		//System.out.println("Creation of trans (" + pos + ")");
					trans[pos] = new Transaction(tlen);
		    }		
		    olditems = trans[pos].size();
		    //System.out.print("trans [" + pos + "] added item ");
		    //lits.get_pat(pat.item( shuffle.pos(i) )).display(15);
		    trans[pos].add(lits.get_pat(pat.item( shuffle.pos(i) )), corrupt ); 
		    nitems += trans[pos].size() - olditems;  // update count of #items
		    //System.out.println("transpossize " + trans[pos].size() + "olditems" + olditems + " nitems " + nitems);
		  }
		  return true;
	}
	
	public int size() 
	{ 
		return nitems; 
	}

	
	public String write()
	{
		String seq ="";
		  int nTranCount = 0, i = 0;
		  for (i = 0; i < ntrans-1; i++){
		    if (trans[i]!=null && trans[i].size()>0)
				  nTranCount++;
		  }
		  if (nTranCount==0) return "";

		  for (i=0; i<ntrans-1; i++){
		    if (trans[i]!=null && trans[i].size()>0)
		    {
		    	seq += trans[i].write(cid);
				seq += " " + " -1 ";		    	
		    }
		  }
		  return seq;
	}


	
}
